﻿using AutoMapper;
using Google.Protobuf.Collections;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.IdentityModel.Tokens;
using Mysqlx.Session;
using MySqlX.XDevAPI.Common;
using Org.BouncyCastle.Crypto;
using socialnetworkApp.Core;
using socialnetworkApp.Core.JwtService;
using socialnetworkApp.Core.QQSendEmailConfig;
using socialnetworkApp.Domain;
using socialnetworkApp.Domain.Dto.Input;
using socialnetworkApp.Domain.Dto.InternalUse.OutPut;
using socialnetworkApp.Domain.Dto.Output;
using socialnetworkApp.Domain.IRepository;
using socialnetworkApp.Domain.Manager;
using socialnetworkApp.Domain.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;

namespace socialnetworkApp.Service.UsersService
{
    public class UserService : IUserService
    {
        private readonly UsersManager  _usersManager;
        private readonly FriendsManager _friendsManager;
        private readonly IAuthenticateService _authenservice;
        private readonly ISendEmailService _sendemailservice;
        private readonly AdminManager _adminmanager;
        private readonly IMapper _mapper;

        private readonly IMemoryCache _memoryCache;

        public UserService(UsersManager usersManager,
            IAuthenticateService _authenticateService,
            ISendEmailService sendEmailService,
            FriendsManager friendsManager,
            IMemoryCache memoryCache,AdminManager adminManager,
           IMapper mapper) {
            _friendsManager = friendsManager;
        _usersManager = usersManager;
        _authenservice = _authenticateService;
            _sendemailservice = sendEmailService;
            _memoryCache = memoryCache;
            _adminmanager = adminManager;
            _mapper = mapper;
        }

        /// <summary>
        /// 获取用户好友列表
        /// </summary>
        /// <param name="userIfoInput"></param>
        /// <returns></returns>
        public async Task<ResponseResult<List<UserFriendsListOutput>>> GetFriendsList(GetUserIfoInput userIfoInput)
        {

            List<UserFriendsListOutput> outputs = new List<UserFriendsListOutput>();
            Friends friend = new Friends { Uid =userIfoInput.Id};
            //获取我朋友的id
            var firendlsit = await _friendsManager.GetfriendId(friend);

            List<Users> usersList = firendlsit.Select(fitem => new Users ( fitem.Fid) ).ToList();

         var result = await  _usersManager.GetUserListById(usersList);
            if (result ==null)
            {

                return ResponseResult<List<UserFriendsListOutput>>.FailResult("用户暂时没好友!");
            }
            outputs = result.Select(item => new UserFriendsListOutput 
            {Id=item.Id,
            Email =item.Email,
            NickName=item.Nickname,
            HeadeImg=item.HeadeImg,
            Signature=item.Signature
            
            }).ToList();
           

            return ResponseResult<List<UserFriendsListOutput>>.SuccessResult(outputs);
        }

        //static string FindChildNodeName(GetPermissionInfoOutput node, string id)
        //{
        //    if (node.Id == id)
        //    {
        //        return node.Code;
        //    }

        //    foreach (GetPermissionInfoOutput child in node.Children)
        //    {
        //        string name = FindChildNodeName(child, id);
        //        if (name != null)
        //        {
        //            return name;
        //        }
        //    }

        //    return null;
        //}
        /// <summary>
        /// 将多个List<string>  合并为一个List<string> 并且去重复
        /// </summary>
        /// <param name="lists">多个list集合</param>
        /// <returns></returns>
        //public static List<string> MergeAndRemoveDuplicates(List<List<string>> lists)
        //{
        //    return lists.SelectMany(x => x).Distinct().ToList();
        //}

        //public async Task<ReturnTwoCodeOutput> RetrieveAndDifferentiatePermissionsAsync(List<GetPermissionInfoOutput> list, List<string>? roleIds)
        //{

        //    List<string>? RouteCode = new List<string>();
        //    List<string>? ButtonCode = new List<string>();
        //    //获取权限信息
        //    var roleListInfo = await _adminmanager.GetRoleInfoById(roleIds);
        //    List<List<string>> Routeslists = new List<List<string>>();
        //    List<List<string>> Buttonslists = new List<List<string>>();
        //    //将每个角色权限信息中的route Id和button 的 id拿到
        //    foreach (var role in roleListInfo)
        //    {
        //        if (role.Routes != null)
        //        {
        //            var Routesinfo = JsonSerializer.Deserialize<List<string>>(role.Routes);
        //            if (Routesinfo != null)
        //            {
        //                Routeslists.Add(Routesinfo);
        //            }
        //        }

        //        if (role.Buttons != null)
        //        {
        //            var Buttonsinfo = JsonSerializer.Deserialize<List<string>>(role.Buttons);
        //            if (Buttonsinfo != null)
        //            {
        //                Buttonslists.Add(Buttonsinfo);
        //            }
        //        }
        //    }
        //    //将每一个角色权限路由和按钮权限的的id都拿到
        //    var RouteIds = MergeAndRemoveDuplicates(Routeslists);
        //    var ButtonIds = MergeAndRemoveDuplicates(Buttonslists);
        //    //根据路由id获取路由的权限code（权限值）
        //    if (!RouteIds.IsNullOrEmpty())
        //    {

        //        //var Routes = JsonSerializer.Deserialize<List<string>>(userinfo.Routes);


        //        // 遍历 ID 数组
        //        for (int i = 0; i < RouteIds.Count; i++)
        //        {
        //            // 找到与当前 ID 匹配的节点
        //            GetPermissionInfoOutput node = list.Find(n => n.Id == RouteIds[i]);

        //            // 如果找到节点，递归地查找子节点中是否存在匹配的 ID，并将名称添加到结果数组中
        //            if (node != null)
        //            {
        //                if (node.Id == RouteIds[i])
        //                {
        //                    RouteCode.Add(node.Code);
        //                }

        //            }
        //        }
        //    }
        //    //根据buttom的id获取路由的权限code（权限值）
        //    if (!ButtonIds.IsNullOrEmpty())
        //    {
        //        //var Buttons = JsonSerializer.Deserialize<List<string>>(userinfo.Buttons);

        //        // 遍历 ID 数组
        //        for (int i = 0; i < ButtonIds.Count; i++)
        //        {
        //            // 找到与当前 ID 匹配的节点
        //            GetPermissionInfoOutput node = list.Find(n => n.Id == ButtonIds[i]);

        //            // 如果找到节点，递归地查找子节点中是否存在匹配的 ID，并将名称添加到结果数组中
        //            if (node != null)
        //            {
        //                if (node.Id == ButtonIds[i])
        //                {
        //                    ButtonCode.Add(node.Code);
        //                }

        //            }
        //        }
        //    }

        //    ReturnTwoCodeOutput returnTwoCode = new ReturnTwoCodeOutput { RouteCode = RouteCode, ButtonCode = ButtonCode };
        //    return returnTwoCode;
        //}








        public async Task<ResponseResult<UserInfoOutput>> GetUserInfo(GetUserIfoInput input)
        {
            
            UserInfoOutput userInfoOutput;
            List<string>? RouteCode = new List<string>();
            List<string>? ButtonCode = new List<string>();
            List<string>? Roles = null;
            if (input.Id.IsNullOrEmpty())
            {
              userInfoOutput = new UserInfoOutput();
                return  ResponseResult<UserInfoOutput>.Result(0, userInfoOutput, "id不能为空");
            }
            //获取权限菜单
            var result = await _adminmanager.GetPermissionAsyncLisst();
          
            var list = _mapper.Map<List<GetPermissionInfoOutput>>(result);
            Users users = new Users {Id= input.Id };

           var userinfo = await  _usersManager.GetUserInfo(users);
             //拿到用户的所有职位（角色）下的权限Id
             var roleIds= JsonSerializer.Deserialize<List<string>>(userinfo.Roles);
            //获取区分权限值
            var RouteCodeAndButtonCode= await  _adminmanager.RetrieveAndDifferentiatePermissionsAsync(list, roleIds);
            RouteCode = RouteCodeAndButtonCode.RouteCode;
            ButtonCode = RouteCodeAndButtonCode.ButtonCode;
           
            if (!userinfo.Roles.IsNullOrEmpty())
            {
                Roles = JsonSerializer.Deserialize<List<string>>(userinfo.Roles);
            }
            userInfoOutput = new UserInfoOutput {Avatar=userinfo.HeadeImg,Email=userinfo.Email,
                Name=userinfo.Username,Sex=userinfo.Sex,Signature=userinfo.Signature,Routes= RouteCode,
                Buttons=ButtonCode,Roles=Roles};
            return ResponseResult<UserInfoOutput>.SuccessResult(userInfoOutput);

        }

        public async Task<ResponseResult<string>> UpdateEmail(UsersUpdateInput inputDto)
        {
            Users users = new Users { Id = inputDto.Id, Email = inputDto.Email };

            var reuslt = await _usersManager.UpdateEmail(users);
            if (reuslt > 0)
            {
                return ResponseResult<string>.SuccessResult();
            }

            return ResponseResult<string>.FailResult();

        }

        public async Task<ResponseResult<string>> UpdateNickname(UsersUpdateInput inputDto)
        {
        
            Users users = new Users {Id=inputDto.Id, Nickname=inputDto.Nickname };

            var reuslt = await _usersManager.UpdateNickname(users);
           if (reuslt>0)
            {
               
                return ResponseResult<string>.SuccessResult();
            }

            return ResponseResult<string>.FailResult();

        }



        public async Task<ResponseResult<string>> UpdateSex(UsersUpdateInput inputDto)
        {
            Users users = new Users { Id = inputDto.Id, Sex = inputDto.Sex };

            var reuslt = await _usersManager.UpdateSex(users);
            if (reuslt > 0)
            {
                return ResponseResult<string>.SuccessResult();
            }

            return ResponseResult<string>.FailResult();

        }

        public async Task<ResponseResult<string>> UpdateSignature(UsersUpdateInput inputDto)
        {
            Users users = new Users { Id = inputDto.Id, Signature = inputDto.Nickname };

            var reuslt = await _usersManager.UpdateSignature(users);
            if (reuslt > 0)
            {
                return ResponseResult<string>.SuccessResult();
            }

            return ResponseResult<string>.FailResult();

        }

        public async Task<ResponseResult<string>> UpdateUserRoutesAndButtonsAndRoles(UsersUpdateInput usersUpdateInput)
        {
            string Routestr = JsonSerializer.Serialize(usersUpdateInput.Routes);
            string Buttonstr = JsonSerializer.Serialize(usersUpdateInput.Buttons);
            string Rolestr = JsonSerializer.Serialize(usersUpdateInput.Roles);
            Users users = new Users {Id=usersUpdateInput.Id,Routes=Routestr, Buttons =Buttonstr,Roles= Rolestr };

           var result =  await  _usersManager.UpdateUserRoutesAndButtonsAndRoles(users);
            if (result > 0)
            {
                return ResponseResult<string>.SuccessResult();
            }

            return ResponseResult<string>.FailResult();

        }

        public async Task<ResponseResult<LoginInfoOutput>> UserLogin(UserLoginInput userLoginInput)
        {
            Users users = new Users { Username=userLoginInput.Username, Password=userLoginInput.Password };
          
                if (!userLoginInput.Password.IsNullOrEmpty())
                {

              
                     var result =   await   _usersManager.UserLogin(users);
                if (result!=null)
                {
                    //登录成功签发token
                    string?token = null;
                    if (_authenservice.IsAuthenticated(userLoginInput.Username, userLoginInput.Password, result.Id, out token))
                    {
                        LoginInfoOutput loginInfoOutput = new LoginInfoOutput {Token=token };

                        return  ResponseResult<LoginInfoOutput>.SuccessResult(loginInfoOutput);
                    }


                }
                    return ResponseResult<LoginInfoOutput>.Result(0, null, "用户名或密码错误");
                }
                return ResponseResult<LoginInfoOutput>.Result(0, null, "密码不能为空！");
      


        }
        /// <summary>
        /// 发送验证码
        /// </summary>
        /// <param name="userLoginInput"></param>
        /// <returns></returns>
        public ResponseResult<string> UserSendValidateCode(UserLoginInput userLoginInput)
        {
            if (!userLoginInput.Email.IsNullOrEmpty())
            {
                if (_sendemailservice.ValidateCodeSendEmail(userLoginInput.Email))
                {
                    return ResponseResult<string>.Result(ResultStatus.Success, null, "请求发送验证码成功！");
                }
            }
            return  ResponseResult<string>.Result(0, null, "邮箱不能为空");
        }



        /// <summary>
        /// 验证码登录
        /// </summary>
        /// <param name="userLoginInput"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<ResponseResult<LoginInfoOutput>> UserValidateCodeLogin(UserLoginInput userLoginInput)
        {
            //判断用户验证码和
           var  CacheCode = _memoryCache.Get(userLoginInput.Email);
            if (CacheCode==null)
            {
                return ResponseResult<LoginInfoOutput>.Result(ResultStatus.Error, null, "您没发送验证码！");
            }
            if (!string.IsNullOrEmpty(CacheCode.ToString()))
            {
                if (CacheCode.Equals(userLoginInput.ValidateCode))
                {
                    var id = Guid.NewGuid().ToString();
                    var nickName = "新用户"+ Guid.NewGuid().ToString();
                    Users users = new Users { Email = userLoginInput.Email};

                    var result = await  _usersManager.IsExistUser(users);
                    Users InserUser ;
                    //判断用户是否注册到数据库中了,没注册就注册账号
                    if (result==null)
                    {    ///默认密码123456
                        Users InserUsers = new Users { Email = userLoginInput.Email, Id = id, Nickname = nickName, Password = "123456" };
                        if (Convert.ToInt32(await _usersManager.AddUser(InserUsers))<=0)
                        {
                            return  ResponseResult<LoginInfoOutput>.Result(ResultStatus.Error, null, "服务器异常！");
                        }
                    }
                    //登录成功签发token
                    string? token = null;
                    if (_authenservice.IsAuthenticated(userLoginInput.Email, userLoginInput.ValidateCode,result==null?id:result.Id, out token))
                    {
                        LoginInfoOutput loginInfoOutput = new LoginInfoOutput { Token = token };
                        //登录成功三次存储的验证码
                           _memoryCache.Remove(userLoginInput.Email);
                        return ResponseResult<LoginInfoOutput>.SuccessResult(loginInfoOutput);
                    }


                }
                return ResponseResult<LoginInfoOutput>.Result(ResultStatus.Error, null, "验证码不正确！");
            }
            return ResponseResult<LoginInfoOutput>.Result(ResultStatus.Error, null, "验证码不正确或没有发送验证信息！");
            
        }
    }
}
